package api

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"blockchain-api/internal/models"
	"blockchain-api/pkg/logger"
)

// createTransaction 创建交易
// @Summary 创建交易
// @Description 创建一个新的区块链交易
// @Tags transactions
// @Accept json
// @Produce json
// @Param request body models.CreateTransactionRequest true "创建交易请求"
// @Success 201 {object} models.TransactionResponse
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /transactions [post]
func (s *Server) createTransaction(c *gin.Context) {
	var req models.CreateTransactionRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error("Invalid request body:", err)
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body: " + err.Error()})
		return
	}

	// 验证地址格式
	if !s.services.Wallet.ValidateAddress(req.From) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid from address"})
		return
	}
	if !s.services.Wallet.ValidateAddress(req.To) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid to address"})
		return
	}

	// 创建交易
	transaction, err := s.services.Transaction.CreateTransaction(&req)
	if err != nil {
		logger.Error("Failed to create transaction:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create transaction: " + err.Error()})
		return
	}

	response := models.TransactionResponse{
		ID:        transaction.ID,
		TxHash:    transaction.TxHash,
		From:      transaction.From,
		To:        transaction.To,
		Amount:    transaction.Amount,
		GasPrice:  transaction.GasPrice,
		GasLimit:  transaction.GasLimit,
		Nonce:     transaction.Nonce,
		Data:      transaction.Data,
		Status:    transaction.Status,
		CreatedAt: transaction.CreatedAt.Format("2006-01-02 15:04:05"),
	}

	logger.Info("Transaction created successfully:", transaction.TxHash)
	c.JSON(http.StatusCreated, gin.H{
		"success": true,
		"message": "Transaction created successfully",
		"data":    response,
	})
}

// getTransactions 获取交易列表
// @Summary 获取交易列表
// @Description 获取区块链中的交易列表
// @Tags transactions
// @Produce json
// @Param limit query int false "限制返回数量"
// @Param offset query int false "偏移量"
// @Param status query string false "交易状态"
// @Success 200 {object} map[string]interface{}
// @Failure 500 {object} map[string]string
// @Router /transactions [get]
func (s *Server) getTransactions(c *gin.Context) {
	// 解析查询参数
	limitStr := c.DefaultQuery("limit", "10")
	offsetStr := c.DefaultQuery("offset", "0")
	status := c.Query("status")

	limit, err := strconv.Atoi(limitStr)
	if err != nil || limit < 0 {
		limit = 10
	}

	offset, err := strconv.Atoi(offsetStr)
	if err != nil || offset < 0 {
		offset = 0
	}

	// 获取交易列表
	transactions, total, err := s.services.Transaction.GetTransactions(limit, offset, status)
	if err != nil {
		logger.Error("Failed to get transactions:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get transactions"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data":    transactions,
		"total":   total,
		"limit":   limit,
		"offset":  offset,
	})
}

// getTransaction 获取单个交易
// @Summary 获取单个交易
// @Description 根据交易哈希获取交易详细信息
// @Tags transactions
// @Produce json
// @Param hash path string true "交易哈希"
// @Success 200 {object} models.TransactionResponse
// @Failure 400 {object} map[string]string
// @Failure 404 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /transactions/{hash} [get]
func (s *Server) getTransaction(c *gin.Context) {
	hash := c.Param("hash")
	if hash == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Transaction hash is required"})
		return
	}

	// 获取交易
	transaction, err := s.services.Transaction.GetTransaction(hash)
	if err != nil {
		logger.Error("Failed to get transaction:", err)
		c.JSON(http.StatusNotFound, gin.H{"error": "Transaction not found"})
		return
	}

	response := models.TransactionResponse{
		ID:        transaction.ID,
		TxHash:    transaction.TxHash,
		From:      transaction.From,
		To:        transaction.To,
		Amount:    transaction.Amount,
		GasPrice:  transaction.GasPrice,
		GasLimit:  transaction.GasLimit,
		Nonce:     transaction.Nonce,
		Data:      transaction.Data,
		Status:    transaction.Status,
		CreatedAt: transaction.CreatedAt.Format("2006-01-02 15:04:05"),
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data":    response,
	})
}

// getAddressBalance 获取地址余额
// @Summary 获取地址余额
// @Description 根据地址获取余额
// @Tags addresses
// @Produce json
// @Param address path string true "地址"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /addresses/{address}/balance [get]
func (s *Server) getAddressBalance(c *gin.Context) {
	address := c.Param("address")
	if address == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Address is required"})
		return
	}

	// 验证地址格式
	if !s.services.Wallet.ValidateAddress(address) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid address format"})
		return
	}

	// 获取余额
	balance, err := s.services.Blockchain.GetAddressBalance(address)
	if err != nil {
		logger.Error("Failed to get address balance:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get address balance"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data": gin.H{
			"address": address,
			"balance": balance,
		},
	})
}

// getAddressTransactions 获取地址交易历史
// @Summary 获取地址交易历史
// @Description 根据地址获取交易历史
// @Tags addresses
// @Produce json
// @Param address path string true "地址"
// @Param limit query int false "限制返回数量"
// @Param offset query int false "偏移量"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /addresses/{address}/transactions [get]
func (s *Server) getAddressTransactions(c *gin.Context) {
	address := c.Param("address")
	if address == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Address is required"})
		return
	}

	// 验证地址格式
	if !s.services.Wallet.ValidateAddress(address) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid address format"})
		return
	}

	// 解析查询参数
	limitStr := c.DefaultQuery("limit", "10")
	offsetStr := c.DefaultQuery("offset", "0")

	limit, err := strconv.Atoi(limitStr)
	if err != nil || limit < 0 {
		limit = 10
	}

	offset, err := strconv.Atoi(offsetStr)
	if err != nil || offset < 0 {
		offset = 0
	}

	// 获取地址交易历史
	transactions, total, err := s.services.Transaction.GetAddressTransactions(address, limit, offset)
	if err != nil {
		logger.Error("Failed to get address transactions:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get address transactions"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data":    transactions,
		"total":   total,
		"limit":   limit,
		"offset":  offset,
	})
}
